classdef AlignCTD_dev < Processor_dev
  % SeaBird's AlignCTD function, which is simply linear interpolation along the
  % data by the provided time offset relative to the read-in sampling interval
  % Derived from Processor_dev
  % Constructor signature: aln = AlignCTD_dev(conn), arg. optional
  %
  % Author: David Goldsmith, Wash. State Dept. of Ecology, dgol461@ecy.wa.gov
  % Original release date: 9/15/2011
  
    properties
      % inherited from Processor_dev
      % inData;
      % castDT;
      % scanRate;
      % ParamID;
      % ParamDesc;
      % SBEprec;
      % EquipID;
        DBdata;
        outData;
        param; % Physical parameter(s) to Align
        reld; % Relative displacement
    end
    
    methods
        function aln = AlignCTD_dev(conn) % Constructor
            aln = aln@Processor_dev();
            if nargin, aln.doSubstantive(conn); end
        end
        
        function doSubstantive(obj, conn)
            global instHeaderData mSB
            if nargin-1, obj.getDBdata(conn, 'Align'); end
            if ~isempty(obj.DBdata)
                for field=fieldnames(obj.DBdata)'
                    field = field{:};
                    obj.reld = instHeaderData.scanRate * obj.DBdata.(field){1};
                    appPar = regexp(obj.DBdata.(field){2}, '_', 'split');
                    q = query_dev(conn, struct('cols', {{'MatlabProcessingID'}},...
                                               'tbls', {{'Parameter'}}));
                    if mSB, q.setPropVals('cols', 'SBEPrecision', 1); end
                    where = ['ParameterID IN (' sprintf('%s, ', appPar{1:end-1})];
                    where = [where appPar{end} ')'];
                    q.setPropVals('where', {where})
                    q.submitStatement
                    appPar = q.result(:,1);
                    if mSB, SBEprec = q.result(:,2); 
                    else obj.SBEprec = 0; end
                    for n=1:numel(appPar)
                        obj.param = appPar{n};
                        if mSB, obj.SBEprec = SBEprec{n}; end
                        obj.outData.(obj.param) = [];
                        obj.mainFormula
                    end
                end
            end
        end
                
        function mainFormula(obj)
            global instHeaderData
            global P T C H X F U R dov S DOS

            x = eval([obj.param '.outData']);
            
            if obj.SBEprec % Unless we're in "mSB mode," this should be 0
                if ismember(obj.param, {'U', 'R'})
                    pow = round2(log10(abs(x)), 1, 'fix') + 1 ...
                                 - eval([obj.param '.SBEprec']);
                    x = round2(x, 10.^pow);
                else
                    x = round2(x, eval([obj.param '.SBEprec']));
                end
            end
            
            if obj.reld > 0
                wholPart = floor(obj.reld);
                fracPart = obj.reld - wholPart;
                x(1:end-wholPart) = x(wholPart+1:end);
                x(end-wholPart+1:end) = instHeaderData.BadFlag;
                if fracPart
                    d = diff(x);
                    x(1:end-1) = x(1:end-1) + fracPart*d;
                    x(end) = instHeaderData.BadFlag;
                end
            elseif obj.reld < 0
                wholPart = ceil(obj.reld);
                fracPart = obj.reld - wholPart;
                x(1-wholPart:end) = x(1:end+wholPart);
                x(1:-wholPart) = instHeaderData.BadFlag;
                if fracPart
                    d = diff(x);
                    x(2:end) = x(2:end) + fracPart*d;
                    x(1) = instHeaderData.BadFlag;
                end
            end
            
            if obj.SBEprec % As above
                if exist('pow', 'var')
                    pow = round2(log10(abs(x)), 1, 'fix') + 1 ...
                                 - eval([obj.param '.SBEprec']);
                    x = round2(x, 10.^pow);
                else
                    x = round2(x, eval([obj.param '.SBEprec']));
                end
            end

            obj.outData.(obj.param) = x;
        end
        
        function delete(obj) % Destructor
            % Here in case I need it
        end
    end
    
end